Skip to content

ci: introduce towncrier to generate changelog from fragments#5187

Merged
lzchen merged 12 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/towncrier-review
May 12, 2026
Merged

ci: introduce towncrier to generate changelog from fragments#5187
lzchen merged 12 commits into
open-telemetry:mainfrom
MikeGoldsmith:mike/towncrier-review

Conversation

@MikeGoldsmith
Copy link
Copy Markdown
Member

@MikeGoldsmith MikeGoldsmith commented May 8, 2026

Description

Replace manual CHANGELOG.md editing with towncrier fragment-based changelog management. Each PR adds a small text file in .changelog/ instead of editing the changelog directly, eliminating merge conflicts.

This supersedes #4382 (PoC by @emdneto) — builds on that foundation with updates for current main, additional features informed by how pip, pytest, attrs, and Twisted use towncrier.

Fixes #4307
Fixes #4309

What changed

Core towncrier setup:

  • pyproject.toml: towncrier config with 5 fragment types (added, changed, deprecated, removed, fixed), pinned towncrier==25.8.0 in CI
  • scripts/changelog_template.j2: custom Jinja2 template matching existing changelog format
  • CHANGELOG.md: <!-- changelog start --> marker added above existing ## Unreleased section; existing entries preserved as-is and can be migrated to fragments at the next release

CI & workflows:

  • .github/workflows/changelog.yml: rejects direct CHANGELOG.md edits, validates fragments exist via git diff, previews rendered changelog with towncrier build --draft
  • .github/workflows/prepare-release-branch.yml: sed replaced with towncrier build
  • .github/workflows/prepare-patch-release.yml: same + adds backport step to sync changelog to main

Documentation:

  • CONTRIBUTING.md: changelog section with style guidance (imperative tone, package prefix, <80 chars)
  • RELEASING.md: updated backporting section

Improvements over #4382

  • Added deprecated and removed categories (original only had added/changed/fixed)
  • Style guidance in CONTRIBUTING.md
  • towncrier added to dev dependency group
  • Updated bot references to otelbot[bot]
  • Based on current main (original PR was months stale)

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

  • towncrier build --draft --version "Unreleased" — verified fragment parsing and categorized output
  • towncrier build --yes --version "1.42.0/0.63b0" — verified full build inserts into CHANGELOG.md at marker, deletes fragments
  • Verified CI changelog preview step renders correctly

Does This PR Require a Contrib Repo Change?

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@MikeGoldsmith MikeGoldsmith requested a review from a team as a code owner May 8, 2026 12:05
@MikeGoldsmith MikeGoldsmith added the Skip Changelog PRs that do not require a CHANGELOG.md entry label May 8, 2026
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 8, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

Replace manual CHANGELOG.md editing with towncrier fragment-based changelog
management. Each PR adds a small text file in .changelog/ instead of editing
the changelog directly, eliminating merge conflicts.

Changes:
- Add towncrier configuration in pyproject.toml with 5 fragment types
  (added, changed, deprecated, removed, fixed)
- Replace sed-based changelog generation in release workflows with
  towncrier build
- Add changelog backport step to patch release workflow
- Update CI to use towncrier check for fragment validation
- Add pre-commit check via scripts/check_changelog_fragment.py
- Add tox environments: changelog (preview) and new-changelog (create)
- Add contributor documentation in CONTRIBUTING.md
- Convert existing unreleased entries to fragment files
- Add custom Jinja2 template for changelog output

Based on the proof-of-concept in open-telemetry#4382 by @emdneto.

Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com>
Assisted-by: Claude Opus 4.6
@MikeGoldsmith MikeGoldsmith force-pushed the mike/towncrier-review branch from 6d7185f to f664c36 Compare May 8, 2026 12:09
Existing ## Unreleased entries stay in CHANGELOG.md — the towncrier
marker is placed above them. Fragment migration can happen at the
next release.

Assisted-by: Claude Opus 4.6
- Regenerate misc.yml for new changelog/new-changelog tox envs
- Update uv.lock for towncrier dependency
- Apply ruff formatting to check_changelog_fragment.py

Assisted-by: Claude Opus 4.6
Copy link
Copy Markdown
Member

@emdneto emdneto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. Thanks for resurrecting this 👍🏻 Left some comments

Comment thread tox.ini Outdated
Comment thread .pre-commit-config.yaml Outdated
@aabmass
Copy link
Copy Markdown
Member

aabmass commented May 11, 2026

Awesome thanks Mike! I think we discussed it on slack but I can't remember the pro/cons of town crier vs chloggen.

Per review feedback from @emdneto:
- Remove changelog/new-changelog tox envs (they generate CI jobs)
- Remove pre-commit hook (not all PRs need changelog, PR number
  unknown at commit time)
- Simplify CONTRIBUTING.md to document direct file creation
- Regenerate misc.yml

Assisted-by: Claude Opus 4.6
@MikeGoldsmith
Copy link
Copy Markdown
Member Author

Awesome thanks Mike! I think we discussed it on slack but I can't remember the pro/cons of town crier vs chloggen.

Both tools solve the same problem in a similar way - they replace a single CHANGELOG.md that causes merge conflicts with per-PR fragment files that get compiled at release time.

towncrier chloggen
Language Python (pip install) Go binary
Fragment format Plain text file Structured YAML (change_type, component, note, issues, subtext)
File naming <PR#>.<type> Auto-generated from git branch name
Validation towncrier check (branch-level) chloggen validate (validates against component list)
Used by pip, pytest, attrs, Twisted OTel Collector, Collector Contrib
Install in CI pip install towncrier Requires Go toolchain or pre-built binary

I suggested Towncrier because it's built for use with with python projects, chloggen is a custom OTel tool used by the collector and requires a go binary.

  • Native to the Python ecosystem — pip install in CI, no Go toolchain needed
  • Simpler contributor experience — create a text file with one line, vs filling out a YAML template with multiple fields
  • Already widely adopted by major Python projects, so many contributors will already be familiar with the workflow
  • chloggen's component validation is valuable for collector-contrib (200+ components) but less useful for core Python where all packages release together

I'm not against chloggen, they are very similar. chloggen would tie back into more OTel and has a stricter fragment strucure which would be nice.

Comment thread .github/workflows/changelog.yml Outdated
Comment thread CHANGELOG.md
Comment thread .github/workflows/prepare-release-branch.yml
Comment thread .github/workflows/prepare-patch-release.yml
Copy link
Copy Markdown
Member

@emdneto emdneto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really happy to see that we now have an agreement on this!

My suggestion is we wait for the next release and prioritize merging this ASAP so we can start with a very fresh changelog, and you won't need to map every already merged PR to an entry here. Also, I believe we need at least the same setup for -contrib so the contributor experience is the same in both repos.

Comment thread .github/workflows/changelog.yml
Per review feedback from @aabmass.

Assisted-by: Claude Opus 4.6
- Pin towncrier==25.8.0 for repeatability (per @aabmass)
- Add preview step to print rendered changelog in CI (per @emdneto)
- Fix error messages to reference CONTRIBUTING.md

Assisted-by: Claude Opus 4.6
Remove references to manual ## Unreleased header requirements.
Note that towncrier eliminates changelog merge conflicts during backports.

Assisted-by: Claude Opus 4.6
Comment thread RELEASING.md Outdated
Per feedback from @xrmx — no need to explain the old problem
since it's already solved.

Assisted-by: Claude Opus 4.6
@MikeGoldsmith MikeGoldsmith moved this to Ready for merge in Python PR digest May 12, 2026
@lzchen lzchen merged commit 5ccb54f into open-telemetry:main May 12, 2026
479 of 480 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for merge to Done in Python PR digest May 12, 2026
@MikeGoldsmith MikeGoldsmith deleted the mike/towncrier-review branch May 13, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Skip Changelog PRs that do not require a CHANGELOG.md entry

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Backport workflow as part of releasing is broken Patch release workflow doesn’t backport the patch changelog entry to main branch

5 participants